package network.editor;

import java.awt.Dimension;
import java.awt.Point;
import java.awt.datatransfer.DataFlavor;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragSource;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.TransferHandler;

import xujun.control.XContorlUtil;

import com.mxgraph.model.mxCell;
import com.mxgraph.model.mxGeometry;
import com.mxgraph.swing.util.mxGraphTransferable;
import com.mxgraph.util.mxConstants;
import com.mxgraph.util.mxEvent;
import com.mxgraph.util.mxEventObject;
import com.mxgraph.util.mxEventSource;
import com.mxgraph.util.mxEventSource.mxIEventListener;
import com.mxgraph.util.mxRectangle;

/**
 * 图元选择面板的基类，提供拖动事件，选中事件的集中处理
 * 
 * @author zhangzuoqiang <br/>
 *         Date: Aug 25, 2011
 */
public abstract class AbstarctEditorPanel extends JPanel {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	protected JLabel selectedEntry = null;
	protected mxEventSource eventSource = new mxEventSource(this);

	public AbstarctEditorPanel() {
		// 点击面板时候，取消图元选中状态
		addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent e) {
				clearSelection();
			}
		});
		setTransferHandler(new TransferHandler() {
			/**
			 * 
			 */
			private static final long serialVersionUID = 1L;

			@Override
			public boolean canImport(JComponent comp,
					DataFlavor[] transferFlavors) {
				return true;
			}

		});
	}

	/**
	 * 加载图元图标
	 * 
	 * @param name
	 * @param icon
	 * @param cell
	 */
	protected void addImageLabel(String name, ImageIcon icon, mxCell cell) {
		mxRectangle bounds = (mxGeometry) cell.getGeometry().clone();
		final mxGraphTransferable t = new mxGraphTransferable(
				new Object[] { cell }, bounds);

		// 设置图片的尺寸，最大为32*32
		if (icon != null) {
			if (icon.getIconWidth() > 32 || icon.getIconHeight() > 32) {
				icon = new ImageIcon(icon.getImage().getScaledInstance(32, 32,
						0));
			}
		}
		final JLabel entry = new JLabel(icon);
		entry.setPreferredSize(new Dimension(50, 50));
		entry.setFont(XContorlUtil.FONT_12_PLAIN);
		entry.setVerticalTextPosition(JLabel.BOTTOM);
		entry.setHorizontalTextPosition(JLabel.CENTER);
		entry.setIconTextGap(0);
		entry.setToolTipText(name);
		entry.setText(name);
		entry.addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent e) {
				setSelectionEntry(entry, null);
			}
		});
		// 支持图标拖动，复制mxCell到绘图控件上
		DragGestureListener dragGestureListener = new DragGestureListener() {
			public void dragGestureRecognized(DragGestureEvent e) {
				e.startDrag(null, mxConstants.EMPTY_IMAGE, new Point(), t, null);
			}
		};

		DragSource dragSource = new DragSource();
		dragSource.createDefaultDragGestureRecognizer(entry,
				DnDConstants.ACTION_COPY, dragGestureListener);
		add(entry);
	}

	public void addListener(String eventName, mxIEventListener listener) {
		eventSource.addListener(eventName, listener);
	}

	public void removeListener(mxIEventListener listener) {
		eventSource.removeListener(listener);
	}

	public boolean isEventsEnabled() {
		return eventSource.isEventsEnabled();
	}

	public void removeListener(mxIEventListener listener, String eventName) {
		eventSource.removeListener(listener, eventName);
	}

	public void setEventsEnabled(boolean eventsEnabled) {
		eventSource.setEventsEnabled(eventsEnabled);
	}

	protected void setSelectionEntry(JLabel entry, mxGraphTransferable t) {
		JLabel previous = selectedEntry;
		selectedEntry = entry;

		if (previous != null) {
			previous.setBorder(null);
			previous.setOpaque(false);
		}

		if (selectedEntry != null) {
			selectedEntry.setBorder(ShadowBorder.getSharedInstance());
			selectedEntry.setOpaque(true);
		}

		eventSource.fireEvent(new mxEventObject(mxEvent.SELECT, "entry",
				selectedEntry, "transferable", t, "previous", previous));
	}

	protected void clearSelection() {
		setSelectionEntry(null, null);
	}
}